/*
 * TraitEditorPanel.java
 *
 * Created on January 29, 2008, 4:16 PM
 * @author  Ryan J. Bovorasmy
 * 
 * Revision log: 
 * 2-7-2008 to 2-10-2008 - Paul Kratt - Added pull and push for organism action strategy code.
    Added setEdit to set the organism that this panel is editing.
 * 4-20-2008 - Paul Kratt - Bugfix... Action code wasn't being pulled out of the gene into the text field. (Pushing was fine)
 */
package protovitae.ui;

import java.awt.Color;
import java.util.Map.Entry;
import javax.swing.DefaultComboBoxModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.JTextComponent;
import protovitae.data.ConcreteGene;
import protovitae.data.Organism.ATTRIBUTE_TYPE;

public class TraitEditorPanel extends javax.swing.JPanel {
    private MainWindow parent = null;
    private ConcreteGene genedit = null; //The gene this panel is currently editing.

    /** Creates new form TraitEditorPanel */
    public TraitEditorPanel(MainWindow parent) {
        this.parent = parent;
        initComponents();
        setUpTextAreas();
        
        //Remove Exposed attribute overrides, they're not used
        tabTraitDetails.remove(pnlAttributes);
        tabTraitDetails.revalidate();
    }
    
    /** Set the trait we are editing with this panel **/
    public void setEdit(ConcreteGene genedit){
        this.genedit = genedit;
        txtActCode.setText(genedit.getActStrategy().getCode());
        txtMoveCode.setText(genedit.getMoveStrategy().getCode());
        txtAttackCode.setText(genedit.getAttackStrategy().getCode());
        txtEatCode.setText(genedit.getEatStrategy().getCode());
        txtDanceCode.setText(genedit.getDanceStrategy().getCode());
        txtMateCode.setText(genedit.getMateStrategy().getCode());
        txtTraitName.setText(genedit.getName());
        //Populate exposed attributes
        
        DefaultTableModel attributes = (DefaultTableModel) tblAttributes.getModel();
        for(Entry item : genedit.getExposedOverrides().entrySet()){
            String[] additions = {item.getKey().toString(), item.getValue().toString()};
            attributes.addRow(additions);
        }
    }
    
    /** Return the thing we're editing **/
    public ConcreteGene getEdit(){
        return genedit;
    }

    public void paste() {
        //We're going to have to cheat, and just use the current tab for this one
        switch (tabTraitDetails.getSelectedIndex()) {
            /*case 0:
                ((JTextComponent) txtAttributeModCode).paste();
                break;*/
            case 0: //Act
                txtActCode.paste();
                break;
            case 1: //Move
                txtMoveCode.paste();
                break;
            case 2: //Attack
                txtAttackCode.paste();
                break;
            case 3: //Eat
                txtEatCode.paste();
                break;
            case 4: //Dance
                txtDanceCode.paste();
                break;
            case 5: //Mate
                txtMateCode.paste();
                break;
            default:
                break;
        }
    }

    public void copy() {
        //We're going to have to cheat, and just use the current tab for this one
        switch (tabTraitDetails.getSelectedIndex()) {
            /*case 0:
                ((JTextComponent) txtAttributeModCode).copy();
                break;*/
            case 0: //Act
                txtActCode.copy();
                break;
            case 1: //Move
                txtMoveCode.copy();
                break;
            case 2: //Attack
                txtAttackCode.copy();
                break;
            case 3: //Eat
                txtEatCode.copy();
                break;
            case 4: //Dance
                txtDanceCode.copy();
                break;
            case 5: //Mate
                txtMateCode.copy();
                break;
            default:
                break;
        }
    }

    public void cut() {
        //We're going to have to cheat, and just use the current tab for this one

        /* 
         * [2007-12-20, Ryan J. Bovorasmy]
         * Consider creating a custom panel with a getCodePane() method.
         *
         * Example:
         *
         * CodePanel selectedPanel = (CodePanel)tabDetails.getTabComponentAt(tabDetails.getSelectedIndex());
         * ((JTextComponent)selectedPanel.getCodePane()).cut();
         *
         * This would eliminate the need for messy switch logic and hard-coded types.
         * 
         * [2008-2-10, Paul Kratt]
         * It's a good idea, but I'm hoping we can save it for a last resort.
         * There must be a way that we could modify JEdit so that it works like a normal JTextPane,
         * which would allow us to call one function that automatically figures out what has
         * focus and calls it's cut method. It's something we might want to look into after
         * everything else is done.
         */

        switch (tabTraitDetails.getSelectedIndex()) {
            /*case 0:
                ((JTextComponent) txtAttributeModCode).cut();
                break;*/
            case 0: //Act
                txtActCode.cut();
                break;
            case 1: //Move
                txtMoveCode.cut();
                break;
            case 2: //Attack
                txtAttackCode.cut();
                break;
            case 3: //Eat
                txtEatCode.cut();
                break;
            case 4: //Dance
                txtDanceCode.cut();
                break;
            case 5: //Mate
                txtMateCode.cut();
                break;
            default:
                break;
        }
    }

    /** Set up the JEdit text areas for JavaScript **/
    public void setUpTextAreas() {
        txtAttackCode.setTokenMarker(new org.jedit.JavaScriptTokenMarker());
        txtDanceCode.setTokenMarker(new org.jedit.JavaScriptTokenMarker());
        txtEatCode.setTokenMarker(new org.jedit.JavaScriptTokenMarker());
        txtMoveCode.setTokenMarker(new org.jedit.JavaScriptTokenMarker());
        txtMateCode.setTokenMarker(new org.jedit.JavaScriptTokenMarker());
        txtActCode.setTokenMarker(new org.jedit.JavaScriptTokenMarker());
        //Any other control style changes can be made here too.
        //For example if we want to get rid of those ~ at the beginning of lines.
        
        //Populate the list box
        DefaultComboBoxModel combo = (DefaultComboBoxModel)(cmbAttributeModList.getModel());
        for(int i=0; i<ATTRIBUTE_TYPE.values().length; i++){
            combo.addElement(ATTRIBUTE_TYPE.values()[i]);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mnuQuickEdit = new javax.swing.JPopupMenu();
        mnuQECut = new javax.swing.JMenuItem();
        mnuQECopy = new javax.swing.JMenuItem();
        mnuQEPaste = new javax.swing.JMenuItem();
        pnlTraitDetailsContainer = new javax.swing.JPanel();
        pnlTraitDetails = new javax.swing.JPanel();
        pnlTraitName = new javax.swing.JPanel();
        lblTraitName = new javax.swing.JLabel();
        txtTraitName = new javax.swing.JTextField();
        tabTraitDetails = new javax.swing.JTabbedPane();
        pnlAttributes = new javax.swing.JPanel();
        pnlAttributeModifiers = new javax.swing.JPanel();
        cmbAttributeModList = new javax.swing.JComboBox();
        txtAttributeModCode = new javax.swing.JTextField();
        btnAttributeModAdd = new javax.swing.JButton();
        pnlAttributeTable = new javax.swing.JPanel();
        pnlAttributeButtons = new javax.swing.JPanel();
        btnAttributeDelete = new javax.swing.JButton();
        btnAttributeEdit = new javax.swing.JButton();
        scrAttributeTable = new javax.swing.JScrollPane();
        tblAttributes = new javax.swing.JTable();
        pnlActCode = new javax.swing.JPanel();
        pnlActValidate = new javax.swing.JPanel();
        btnSaveAct = new javax.swing.JButton();
        lblActValidate = new javax.swing.JLabel();
        txtActCode = new org.jedit.JEditTextArea();
        pnlMoveCode = new javax.swing.JPanel();
        pnlMoveValidate = new javax.swing.JPanel();
        btnMoveSave = new javax.swing.JButton();
        lblMoveValidate = new javax.swing.JLabel();
        txtMoveCode = new org.jedit.JEditTextArea();
        pnlAttackCode = new javax.swing.JPanel();
        pnlAttackValidate = new javax.swing.JPanel();
        btnAttackSave = new javax.swing.JButton();
        lblAttackValidate = new javax.swing.JLabel();
        txtAttackCode = new org.jedit.JEditTextArea();
        pnlEatCode = new javax.swing.JPanel();
        pnlEatValidate = new javax.swing.JPanel();
        btnEatSave = new javax.swing.JButton();
        lblEatValidate = new javax.swing.JLabel();
        txtEatCode = new org.jedit.JEditTextArea();
        pnlDanceCode = new javax.swing.JPanel();
        pnlDanceValidate = new javax.swing.JPanel();
        btnDanceSave = new javax.swing.JButton();
        lblDanceValidate = new javax.swing.JLabel();
        txtDanceCode = new org.jedit.JEditTextArea();
        pnlMateCode = new javax.swing.JPanel();
        pnlMateValidate = new javax.swing.JPanel();
        btnSaveMate = new javax.swing.JButton();
        lblMateValidate = new javax.swing.JLabel();
        txtMateCode = new org.jedit.JEditTextArea();

        mnuQECut.setText("Cut");
        mnuQuickEdit.add(mnuQECut);

        mnuQECopy.setText("Copy");
        mnuQuickEdit.add(mnuQECopy);

        mnuQEPaste.setText("Paste");
        mnuQuickEdit.add(mnuQEPaste);

        setLayout(new java.awt.BorderLayout());

        pnlTraitDetailsContainer.setLayout(new java.awt.BorderLayout());

        pnlTraitDetails.setBorder(javax.swing.BorderFactory.createTitledBorder("Details"));
        pnlTraitDetails.setLayout(new java.awt.BorderLayout());

        pnlTraitName.setBorder(javax.swing.BorderFactory.createTitledBorder("Name"));
        pnlTraitName.setLayout(new javax.swing.BoxLayout(pnlTraitName, javax.swing.BoxLayout.LINE_AXIS));

        lblTraitName.setText("Trait Name: ");
        pnlTraitName.add(lblTraitName);

        txtTraitName.setColumns(35);
        txtTraitName.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtTraitNameFocusLost(evt);
            }
        });
        pnlTraitName.add(txtTraitName);

        pnlTraitDetails.add(pnlTraitName, java.awt.BorderLayout.NORTH);

        pnlAttributes.setLayout(new java.awt.BorderLayout());

        pnlAttributeModifiers.setLayout(new java.awt.BorderLayout());

        cmbAttributeModList.setModel(parent.getExposedattributes());
        pnlAttributeModifiers.add(cmbAttributeModList, java.awt.BorderLayout.WEST);

        txtAttributeModCode.setColumns(10);
        pnlAttributeModifiers.add(txtAttributeModCode, java.awt.BorderLayout.CENTER);

        btnAttributeModAdd.setText("Add Modifier");
        btnAttributeModAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAttributeModAddActionPerformed(evt);
            }
        });
        pnlAttributeModifiers.add(btnAttributeModAdd, java.awt.BorderLayout.EAST);

        pnlAttributes.add(pnlAttributeModifiers, java.awt.BorderLayout.SOUTH);

        pnlAttributeTable.setBorder(javax.swing.BorderFactory.createTitledBorder("Attribute Table"));
        pnlAttributeTable.setLayout(new java.awt.BorderLayout());

        pnlAttributeButtons.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        pnlAttributeButtons.setLayout(new java.awt.GridLayout(1, 0));

        btnAttributeDelete.setText("Delete Selected");
        btnAttributeDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAttributeDeleteActionPerformed(evt);
            }
        });
        pnlAttributeButtons.add(btnAttributeDelete);

        btnAttributeEdit.setText("Edit Selected");
        btnAttributeEdit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAttributeEditActionPerformed(evt);
            }
        });
        pnlAttributeButtons.add(btnAttributeEdit);

        pnlAttributeTable.add(pnlAttributeButtons, java.awt.BorderLayout.SOUTH);

        tblAttributes.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Attribute", "Modifier"
            }
        ));
        scrAttributeTable.setViewportView(tblAttributes);

        pnlAttributeTable.add(scrAttributeTable, java.awt.BorderLayout.CENTER);

        pnlAttributes.add(pnlAttributeTable, java.awt.BorderLayout.CENTER);

        tabTraitDetails.addTab("Exposed Attributes", pnlAttributes);

        pnlActCode.setLayout(new java.awt.BorderLayout());

        pnlActValidate.setLayout(new javax.swing.BoxLayout(pnlActValidate, javax.swing.BoxLayout.LINE_AXIS));

        btnSaveAct.setText("Save");
        btnSaveAct.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActActionPerformed(evt);
            }
        });
        pnlActValidate.add(btnSaveAct);

        lblActValidate.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        lblActValidate.setText("   Loaded code.");
        pnlActValidate.add(lblActValidate);

        pnlActCode.add(pnlActValidate, java.awt.BorderLayout.PAGE_END);

        txtActCode.setComponentPopupMenu(mnuQuickEdit);
        pnlActCode.add(txtActCode, java.awt.BorderLayout.CENTER);

        tabTraitDetails.addTab("Act", pnlActCode);

        pnlMoveCode.setLayout(new java.awt.BorderLayout());

        pnlMoveValidate.setLayout(new javax.swing.BoxLayout(pnlMoveValidate, javax.swing.BoxLayout.LINE_AXIS));

        btnMoveSave.setText("Save");
        btnMoveSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnMoveSaveActionPerformed(evt);
            }
        });
        pnlMoveValidate.add(btnMoveSave);

        lblMoveValidate.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        lblMoveValidate.setText("   Loaded code.");
        pnlMoveValidate.add(lblMoveValidate);

        pnlMoveCode.add(pnlMoveValidate, java.awt.BorderLayout.PAGE_END);

        txtMoveCode.setComponentPopupMenu(mnuQuickEdit);
        pnlMoveCode.add(txtMoveCode, java.awt.BorderLayout.CENTER);

        tabTraitDetails.addTab("Move", pnlMoveCode);

        pnlAttackCode.setLayout(new java.awt.BorderLayout());

        pnlAttackValidate.setLayout(new javax.swing.BoxLayout(pnlAttackValidate, javax.swing.BoxLayout.LINE_AXIS));

        btnAttackSave.setText("Save");
        btnAttackSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAttackSaveActionPerformed(evt);
            }
        });
        pnlAttackValidate.add(btnAttackSave);

        lblAttackValidate.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        lblAttackValidate.setText("   Loaded code.");
        pnlAttackValidate.add(lblAttackValidate);

        pnlAttackCode.add(pnlAttackValidate, java.awt.BorderLayout.PAGE_END);
        pnlAttackCode.add(txtAttackCode, java.awt.BorderLayout.CENTER);

        tabTraitDetails.addTab("Attack", pnlAttackCode);

        pnlEatCode.setLayout(new java.awt.BorderLayout());

        pnlEatValidate.setLayout(new javax.swing.BoxLayout(pnlEatValidate, javax.swing.BoxLayout.LINE_AXIS));

        btnEatSave.setText("Save");
        btnEatSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnEatSaveActionPerformed(evt);
            }
        });
        pnlEatValidate.add(btnEatSave);

        lblEatValidate.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        lblEatValidate.setText("   Loaded code.");
        pnlEatValidate.add(lblEatValidate);

        pnlEatCode.add(pnlEatValidate, java.awt.BorderLayout.PAGE_END);
        pnlEatCode.add(txtEatCode, java.awt.BorderLayout.CENTER);

        tabTraitDetails.addTab("Eat", pnlEatCode);

        pnlDanceCode.setLayout(new java.awt.BorderLayout());

        pnlDanceValidate.setLayout(new javax.swing.BoxLayout(pnlDanceValidate, javax.swing.BoxLayout.LINE_AXIS));

        btnDanceSave.setText("Save");
        btnDanceSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnDanceSaveActionPerformed(evt);
            }
        });
        pnlDanceValidate.add(btnDanceSave);

        lblDanceValidate.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        lblDanceValidate.setText("   Loaded code.");
        pnlDanceValidate.add(lblDanceValidate);

        pnlDanceCode.add(pnlDanceValidate, java.awt.BorderLayout.PAGE_END);
        pnlDanceCode.add(txtDanceCode, java.awt.BorderLayout.CENTER);

        tabTraitDetails.addTab("Dance", pnlDanceCode);

        pnlMateCode.setLayout(new java.awt.BorderLayout());

        pnlMateValidate.setLayout(new javax.swing.BoxLayout(pnlMateValidate, javax.swing.BoxLayout.LINE_AXIS));

        btnSaveMate.setText("Save");
        btnSaveMate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveMateActionPerformed(evt);
            }
        });
        pnlMateValidate.add(btnSaveMate);

        lblMateValidate.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        lblMateValidate.setText("   Loaded code.");
        pnlMateValidate.add(lblMateValidate);

        pnlMateCode.add(pnlMateValidate, java.awt.BorderLayout.PAGE_END);
        pnlMateCode.add(txtMateCode, java.awt.BorderLayout.CENTER);

        tabTraitDetails.addTab("Mate", pnlMateCode);

        pnlTraitDetails.add(tabTraitDetails, java.awt.BorderLayout.CENTER);

        pnlTraitDetailsContainer.add(pnlTraitDetails, java.awt.BorderLayout.CENTER);

        add(pnlTraitDetailsContainer, java.awt.BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents

    private void btnAttributeModAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAttributeModAddActionPerformed
        DefaultTableModel attributes = (DefaultTableModel) tblAttributes.getModel();

        String[] additions = {cmbAttributeModList.getSelectedItem().toString(), txtAttributeModCode.getText()};
        attributes.addRow(additions);
        genedit.getExposedOverrides().put(cmbAttributeModList.getSelectedItem().toString(), txtAttributeModCode.getText());
        //We should probably write a function to validate these...
    }//GEN-LAST:event_btnAttributeModAddActionPerformed

    private void btnAttributeDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAttributeDeleteActionPerformed
        DefaultTableModel attributes = (DefaultTableModel) tblAttributes.getModel();

        if (tblAttributes.getSelectedRow() >= 0) {
            attributes.removeRow(tblAttributes.getSelectedRow());
        }
    }//GEN-LAST:event_btnAttributeDeleteActionPerformed

    private void btnAttributeEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAttributeEditActionPerformed
        DefaultTableModel attributes = (DefaultTableModel) tblAttributes.getModel();
        String attr, code;
        int selrow = tblAttributes.getSelectedRow();

        if (selrow >= 0) {
            attr = (String) attributes.getValueAt(selrow, 0);
            code = (String) attributes.getValueAt(selrow, 1);

            DefaultComboBoxModel thelist = ((DefaultComboBoxModel) (cmbAttributeModList.getModel()));
            for (int i = 0; i < thelist.getSize(); i++) {
                if ((thelist.getElementAt(i).toString()).equalsIgnoreCase(attr)) {
                    cmbAttributeModList.setSelectedIndex(i);
                    break;
                }
                if (i == thelist.getSize() - 1) {
                    //We never found it? Hey!
                    //Let's add it to the list, because I can't think of any better solution
                    cmbAttributeModList.addItem(attr);
                    cmbAttributeModList.setSelectedIndex(i + 1);
                    break;
                }
            }
            txtAttributeModCode.setText(code);
            attributes.removeRow(selrow);
        }
    }//GEN-LAST:event_btnAttributeEditActionPerformed

    /** Validate the move code, then save it back to the gene. **/
    private void btnMoveSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMoveSaveActionPerformed
        boolean valid = true;
        try{
            genedit.getMoveStrategy().parse(txtMoveCode.getText());
        }
        catch(Exception e){
            valid=false;
        }
        
        if(valid){
            lblMoveValidate.setForeground(new Color(0,128,0));
            lblMoveValidate.setText("   Changes saved.");
            //Future idea: Make these disappear after a few seconds?
        }
        else{
            lblMoveValidate.setForeground(Color.RED);
            lblMoveValidate.setText("   Invalid code!");
        }
    }//GEN-LAST:event_btnMoveSaveActionPerformed

    private void btnAttackSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAttackSaveActionPerformed
        boolean valid = true;
        try{
            genedit.getAttackStrategy().parse(txtAttackCode.getText());
        }
        catch(Exception e){
            valid=false;
        }
        
        if(valid){
            lblAttackValidate.setForeground(new Color(0,128,0));
            lblAttackValidate.setText("   Changes saved.");
        }
        else{
            lblAttackValidate.setForeground(Color.RED);
            lblAttackValidate.setText("   Invalid code!");
        }
    }//GEN-LAST:event_btnAttackSaveActionPerformed

    private void btnEatSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEatSaveActionPerformed
        boolean valid = true;
        try{
            genedit.getEatStrategy().parse(txtEatCode.getText());
        }
        catch(Exception e){
            valid=false;
        }
        
        if(valid){
            lblEatValidate.setForeground(new Color(0,128,0));
            lblEatValidate.setText("   Changes saved.");
        }
        else{
            lblEatValidate.setForeground(Color.RED);
            lblEatValidate.setText("   Invalid code!");
        }
    }//GEN-LAST:event_btnEatSaveActionPerformed

    private void btnDanceSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDanceSaveActionPerformed
        boolean valid = true;
        try{
            genedit.getDanceStrategy().parse(txtDanceCode.getText());
        }
        catch(Exception e){
            valid=false;
        }
        
        if(valid){
            lblDanceValidate.setForeground(new Color(0,128,0));
            lblDanceValidate.setText("   Changes saved.");
        }
        else{
            lblDanceValidate.setForeground(Color.RED);
            lblDanceValidate.setText("   Invalid code!");
        }
    }//GEN-LAST:event_btnDanceSaveActionPerformed

    private void btnSaveMateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveMateActionPerformed
        boolean valid = true;
        try{
            genedit.getMateStrategy().parse(txtMateCode.getText());
        }
        catch(Exception e){
            valid=false;
        }
        
        if(valid){
            lblMateValidate.setForeground(new Color(0,128,0));
            lblMateValidate.setText("   Changes saved.");
        }
        else{
            lblMateValidate.setForeground(Color.RED);
            lblMateValidate.setText("   Invalid code!");
        }
    }//GEN-LAST:event_btnSaveMateActionPerformed

    /** Update the trait name when this control loses focus **/
    private void txtTraitNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtTraitNameFocusLost
        if(genedit!=null)
            genedit.setName(txtTraitName.getText()); //Set the trait name
    }//GEN-LAST:event_txtTraitNameFocusLost

    private void btnSaveActActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActActionPerformed
        boolean valid = true;
        try{
            genedit.getActStrategy().parse(txtActCode.getText());
        }
        catch(Exception e){
            valid=false;
        }
        
        if(valid){
            lblActValidate.setForeground(new Color(0,128,0));
            lblActValidate.setText("   Changes saved.");
        }
        else{
            lblActValidate.setForeground(Color.RED);
            lblActValidate.setText("   Invalid code!");
        }
}//GEN-LAST:event_btnSaveActActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAttackSave;
    private javax.swing.JButton btnAttributeDelete;
    private javax.swing.JButton btnAttributeEdit;
    private javax.swing.JButton btnAttributeModAdd;
    private javax.swing.JButton btnDanceSave;
    private javax.swing.JButton btnEatSave;
    private javax.swing.JButton btnMoveSave;
    private javax.swing.JButton btnSaveAct;
    private javax.swing.JButton btnSaveMate;
    private javax.swing.JComboBox cmbAttributeModList;
    private javax.swing.JLabel lblActValidate;
    private javax.swing.JLabel lblAttackValidate;
    private javax.swing.JLabel lblDanceValidate;
    private javax.swing.JLabel lblEatValidate;
    private javax.swing.JLabel lblMateValidate;
    private javax.swing.JLabel lblMoveValidate;
    private javax.swing.JLabel lblTraitName;
    private javax.swing.JMenuItem mnuQECopy;
    private javax.swing.JMenuItem mnuQECut;
    private javax.swing.JMenuItem mnuQEPaste;
    private javax.swing.JPopupMenu mnuQuickEdit;
    private javax.swing.JPanel pnlActCode;
    private javax.swing.JPanel pnlActValidate;
    private javax.swing.JPanel pnlAttackCode;
    private javax.swing.JPanel pnlAttackValidate;
    private javax.swing.JPanel pnlAttributeButtons;
    private javax.swing.JPanel pnlAttributeModifiers;
    private javax.swing.JPanel pnlAttributeTable;
    private javax.swing.JPanel pnlAttributes;
    private javax.swing.JPanel pnlDanceCode;
    private javax.swing.JPanel pnlDanceValidate;
    private javax.swing.JPanel pnlEatCode;
    private javax.swing.JPanel pnlEatValidate;
    private javax.swing.JPanel pnlMateCode;
    private javax.swing.JPanel pnlMateValidate;
    private javax.swing.JPanel pnlMoveCode;
    private javax.swing.JPanel pnlMoveValidate;
    private javax.swing.JPanel pnlTraitDetails;
    private javax.swing.JPanel pnlTraitDetailsContainer;
    private javax.swing.JPanel pnlTraitName;
    private javax.swing.JScrollPane scrAttributeTable;
    private javax.swing.JTabbedPane tabTraitDetails;
    private javax.swing.JTable tblAttributes;
    private org.jedit.JEditTextArea txtActCode;
    private org.jedit.JEditTextArea txtAttackCode;
    private javax.swing.JTextField txtAttributeModCode;
    private org.jedit.JEditTextArea txtDanceCode;
    private org.jedit.JEditTextArea txtEatCode;
    private org.jedit.JEditTextArea txtMateCode;
    private org.jedit.JEditTextArea txtMoveCode;
    private javax.swing.JTextField txtTraitName;
    // End of variables declaration//GEN-END:variables
}
